package com.tanhua.app.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.api.mongo.SoundApi;
import com.tanhua.app.interceptor.UserHolder;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Sound;
import com.tanhua.domain.vo.SoundVo;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.Calendar;
import java.util.List;

/**
 * @author ：DaLin
 * @date ：2021/1/12 10:29
 */
@Service
public class SoundService {
    @Autowired
    private FdfsWebServer webServer;
    @Autowired
    private FastFileStorageClient client;
    @Reference
    private SoundApi soundApi;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Reference
    private UserInfoApi userInfoApi;

    //桃花传音-发送语音
    public ResponseEntity saveSound(MultipartFile soundFile) throws IOException {
        //将音频上传到fastdfs
        StorePath storePath = client.uploadFile(soundFile.getInputStream(), soundFile.getSize(), FileUtil.extName(soundFile.getOriginalFilename()), null);
        //获取文件路径
        String soundUrl = webServer.getWebServerUrl() + storePath.getFullPath();
        //创建sound对象
        Sound sound = new Sound();
        sound.setId(ObjectId.get());//手动指定主键id
        sound.setSoundUrl(soundUrl);//语音访问路径
        sound.setState(0);//默认未被别人接收
        sound.setUserId(UserHolder.getUserId());//指定语音发布的用户id
        //调用api进行保存
        soundApi.save(sound);
        return ResponseEntity.ok(null);
    }

    //桃花传音-接收语音
    public ResponseEntity findSound() {
        //先查询缓存剩余次数
        String times = stringRedisTemplate.opsForValue().get("soundTimes" + UserHolder.getUserId());
        if (times == null) {//缓存中没有次数就初始化次数为9
            times = "9";
            stringRedisTemplate.opsForValue().set("soundTimes" + UserHolder.getUserId(),times, Duration.ofSeconds(getSecondsNextEarlyMorning()));
        }
         if (Integer.parseInt(times) <= 0) {//当日次数用完。
             return null;
         }
        //查询一次减去一次次数
        //将剩余次数存入缓存
        times = String.valueOf(Integer.parseInt(times) - 1);
         //将每日查询剩余次数放入redis，并于每日凌晨0:00清除缓存
        stringRedisTemplate.opsForValue().set("soundTimes" + UserHolder.getUserId(),times, Duration.ofSeconds(getSecondsNextEarlyMorning()));
        //调用api查询
        List<Sound> soundList = soundApi.find(UserHolder.getUserId());
        if (CollectionUtil.isEmpty(soundList)) {//未查到符合条件的
            return null ;
        }
        //查询的集合中随机取出一个对象
        Sound sound = soundList.get(RandomUtil.randomInt(0, soundList.size()));
        soundApi.update(sound.getId().toHexString());
        //封装vo
        SoundVo vo = new SoundVo();
        UserInfo userInfo = userInfoApi.findByUserId(sound.getUserId());
        vo.setId(sound.getUserId().intValue());
        vo.setAge(userInfo.getAge());
        vo.setAvatar(userInfo.getAvatar());
        vo.setGender(userInfo.getGender());
        vo.setNickname(userInfo.getNickname());
        vo.setSoundUrl(sound.getSoundUrl());//音频访问地址
        vo.setRemainingTimes(Integer.parseInt(times));//当日剩余查询次数
        return ResponseEntity.ok(vo);
    }

    /**
     * 判断当前时间距离第二天凌晨的秒数
     *
     * @return 返回值单位为[s:秒]
     */
    public Long getSecondsNextEarlyMorning() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }
}
